/*
 * Copyright (c) 2014. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

package com.dc.gameserver.extComponents.Scence;



import javolution.util.FastTable;
import javolution.util.FastMap;
import org.jboss.netty.buffer.ChannelBuffer;

import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
* 地图单元对象
*
* @author CHENLEI
*/
@SuppressWarnings("unchecked")
public class MapUnit extends Observable implements Observer {

    private final int ID;  //编号

    /**
     * 游戏对象*
     */
    private final List<WordObject> gameObj = new FastTable<WordObject>();
    private final ConcurrentLinkedQueue<MapUnit> NearUnit = new ConcurrentLinkedQueue<MapUnit>();// 周围单元包括自己
    private final Map<Integer, FastTable<MapUnit>> JiaoMap = new FastMap<Integer, FastTable<MapUnit>>().shared(); //重叠区域
    private final Map<Integer, FastTable<MapUnit>> OldMap = new FastMap<Integer, FastTable<MapUnit>>().shared();  //消失区域
    private final Map<Integer, FastTable<MapUnit>> NewMap = new FastMap<Integer, FastTable<MapUnit>>().shared();  //新增区域

    /**
     * 地图单元格对象       观察者  --- 被观察者
     * @param id
     */
    public MapUnit(int ID) {
        this.ID = ID;
    }
    /**
     * 地图对象操作方式
     */
    enum HadlerStatus{
        ADD,  //添加对象
        DELETE, //删除对象
        SEND  //发送对象消息
    }

    /**
     * 对象加入
     *
     * @param xobj       加入对象
     * @param newMapUnit 新增区域
     */
    public void addUser(WordObject xobj, List<Integer> newMapUnit) {
        gameObj.add(xobj);
        setChanged(); //设置改变
        Vector obj = new Vector();
        obj.add(HadlerStatus.ADD);
        obj.add(xobj);
        obj.add(newMapUnit);
        notifyObservers(obj);
    }

    /**
     * 对象减少
     *
     * @param xobj       减少的对象
     * @param listAreaId 之前所在的区域
     */
    public void delUser(WordObject xobj, List<Integer> listAreaId) {
        gameObj.remove(xobj);
        setChanged(); //设置改变
        Vector obj = new Vector();
        obj.add(HadlerStatus.DELETE);
        obj.add(xobj);
        obj.add(listAreaId);
        notifyObservers(obj);
    }
    /**
     * 对象信息的同步
     *
     * @param xobj
     * @param date
     */
    public void submitSynMsg(WordObject xobj, ChannelBuffer date) {
        setChanged();
        Vector obj = new Vector();
        obj.add(HadlerStatus.SEND);
        obj.add(xobj);
        obj.add(date);
        notifyObservers(obj);
    }
    /**
     * 接收通知改变
     */
    public void update(Observable o, Object arg) {
        Vector obj = null;
        if (arg != null) {
            obj = (Vector) arg;
        }
        assert obj != null;
        switch ((HadlerStatus) obj.get(0)){
            case ADD:
                xobjAddMap(obj);        //对象加入
                break;
            case DELETE:
                xobjleaveMap(obj);      //对象离开
                break;
            case SEND:
                xobjSendMsg(obj);       //对象状态信息
                break;
            default:
                break;
        }
    }

    /**
     * 处理 ---->对象加入
     * 将消息发送给多个对象
     * @param obj
     */
    private void xobjAddMap(Vector obj) {
        WordObject xobj = (WordObject) obj.get(1); //加入的对象
        List<Integer> listAreaId = (List<Integer>) obj.get(2); //新增的区域
        for (int id : listAreaId) {
            if (id == this.ID) {
//                if (xobj instanceof PlayerInstance) {  //人物
//                    PlayerInstance userXobj = (PlayerInstance) xobj;
//                    for (WordObject tobj : gameObj) {
//                        if (tobj instanceof PlayerInstance && userXobj.getID() != tobj.getID()) {
//                            synMsg(userXobj, (PlayerInstance) tobj);
//                            synMsg((PlayerInstance) tobj, userXobj);
//                        } else if (tobj instanceof Monster) {
//                            //怪物信息同步给人
//                            synMsg((Monster) tobj, userXobj);
//                        } else if (tobj instanceof Npc) {
//                            //npc信息同步给人
//                            synMsg((Npc) tobj, userXobj);
//                        }
//                    }
//                } else if (xobj instanceof Monster || xobj instanceof Npc ) {
//                    for (WordObject tobj : gameObj) {
//                        if (tobj instanceof PlayerInstance) {
//                            synMsg(xobj, (PlayerInstance) tobj);
//                        } else if (tobj instanceof Monster) {
//
//                        } else if (tobj instanceof Npc) {
//
//                        }
//                    }
//                }
//                break;
            }
        }

    }

    /**
     * 处理 ---->对象离开
     *  将消息发送给多个对象
     * @param obj
     */
    private void xobjleaveMap(Vector obj) {
        WordObject xobj = (WordObject) obj.get(1);
        List<Integer> listAreaId = (List<Integer>) obj.get(2); //消失的区域
        for (int id : listAreaId) {
            if (id == this.ID) {
//                if (xobj instanceof PlayerInstance) {  //人物
//                    for (WordObject tobj : gameObj) {
//                        if (tobj instanceof PlayerInstance && xobj.getID() != tobj.getID()) {//人物消失
//                            disappearExchangeMsg(xobj, (PlayerInstance) tobj);
//                            disappearExchangeMsg(tobj, (PlayerInstance) xobj);
//                        } else if (tobj instanceof Monster) {//向人广播怪物消失
//                            disappearExchangeMsg(tobj, (PlayerInstance) xobj);
//                        } else if (tobj instanceof Npc) {
//                            disappearExchangeMsg(tobj, (PlayerInstance) xobj);
//                        }
//                    }
//                } else if (xobj instanceof Monster || xobj instanceof Npc ) {  //消失的对象是怪物或者NPC或者是goods
//                    for (WordObject tobj : gameObj) {
//                        if (tobj instanceof PlayerInstance) {
//                            disappearExchangeMsg(xobj, (PlayerInstance) tobj);//怪物没有死亡
//                        } else if (tobj instanceof Monster) {
//                        } else if (tobj instanceof Npc) {
//                        }
//                    }
//                }
//
//                break;
            }
        }
    }

    /**
     * 将消息发送给多个对象
     * 信息广播处理 ---->对象状态信息
     *
     * @param obj 通知携带的信息
     */
    private  void xobjSendMsg(Vector obj){
        WordObject xobj = (WordObject) obj.get(1);
        ChannelBuffer data1 = (ChannelBuffer) obj.get(2);
//        if (xobj instanceof PlayerInstance) {  //人物
//            ChannelBuffer data2 = data1.copy(); //0拷贝 和data1共享一个byte[]
//            for (WordObject tobj : gameObj) {
//                if (tobj instanceof PlayerInstance && xobj.getID() != tobj.getID()) {
//                    ((PlayerInstance) tobj).DirectSynSend(data1);
//                } else if (tobj instanceof Monster) {
//                    ((Monster) tobj).DirectSynSend(data2);
//                } else if (tobj instanceof Npc) {
//                }
//            }
//        } else if (xobj instanceof Monster || xobj instanceof Npc ) {
//            for (WordObject tobj : gameObj) {
//                if (tobj instanceof PlayerInstance) {
//                    ((PlayerInstance) tobj).DirectSynSend(data1);
//                } else if (tobj instanceof Monster) {
//                } else if (tobj instanceof Npc) {
//                }
//            }
//        }
    }



    /**
     *
     * 信息的同步
     *
     * @param mgc 活动角色对象
     * @param tgc 目标接收对象    tgc  is channel
     */
    private void synMsg(WordObject mgc, Object tgc) {
        //发送活动角色对象信息
//        ObjectAppear_response objectAppear_response = new ObjectAppear_response();
//        objectAppear_response.setObj_id(mgc.getID());
//        objectAppear_response.setObj_name(mgc.getName());
//        objectAppear_response.setLocation_x(mgc.getX());
//        objectAppear_response.setLocation_y(mgc.getY());
//        objectAppear_response.setDirection(mgc.getFaceTo());
//        objectAppear_response.setObj_type(mgc.getTypeId());
//        tgc.DirectSynSend(objectAppear_response.getSendData(-2));

        //判断是否在移动中
//        if (mgc instanceof GameCharacter) {
//            GameCharacter mgcx = (GameCharacter) mgc;
//            if (mgc instanceof PlayerInstance) {
//                if (mgcx.getStatus() == 1) { //移动中 发送移动目标包
////                    ObjGoalPosition_response objGoalPosition_response = new ObjGoalPosition_response();
////                    objGoalPosition_response.setObj_id(mgcx.getID());
////                    objGoalPosition_response.setLocation_x(mgcx.getX());
////                    objGoalPosition_response.setLocation_y(mgcx.getY());
////                    tgc.DirectSynSend(objGoalPosition_response.getSendData(-4));
//
//                }
//            }
//        }
    }

    /**
     * 消失数据交互
     *
     * @param obj       发送者
     * @param targetObj 接收者
     */
    private void disappearExchangeMsg(WordObject obj, Object targetObj) {
//        ObjectDisappear_response objectDisappear_response = new ObjectDisappear_response();
//        objectDisappear_response.setObj_id(obj.getID());
//        targetObj.DirectSynSend(objectDisappear_response.getSendData(-3));

    }
    public int getID() {
        return ID;
    }

    public ConcurrentLinkedQueue<MapUnit> getNearUnit() {
        return NearUnit;
    }


    public Map<Integer, FastTable<MapUnit>> getJiaoMap() {
        return JiaoMap;
    }


    public Map<Integer, FastTable<MapUnit>> getOldMap() {
        return OldMap;
    }


    public Map<Integer, FastTable<MapUnit>> getNewMap() {
        return NewMap;
    }

    public List<WordObject> getGameObj() {
        return gameObj;
    }
}
